﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Pavilion.Locks;
using System.ComponentModel;
using Pavilion;
using Pavilion.DesignerTool.ViewTools;
using System.Collections;
using Pavilion.DesignerTool.ViewTools.ConnectableListBox;
using System.Collections.ObjectModel;

namespace Pavilion.DesignerTool
{
    /// <summary>
    /// Interaction logic for LockEditorView.xaml
    /// </summary>
    public partial class LockEditorView : UserControl
    {
        public static readonly DependencyProperty CurrentLinkProperty = DependencyProperty.Register("CurrentLink", typeof(LinkWrapper), typeof(LockEditorView),
            new PropertyMetadata(new PropertyChangedCallback(CurrentLinkChanged)));

        public LinkWrapper CurrentLink { get { return (LinkWrapper)GetValue(CurrentLinkProperty); } set { SetValue(CurrentLinkProperty, value); } }
        public LockEditorViewModel ViewModel { get; set; }

        public LockEditorView()
        {
            InitializeComponent();

            if (!DesignerProperties.GetIsInDesignMode(this))
                DataContext = ViewModel = new LockEditorViewModel();
        }

        public void SetLink(LinkWrapper linkWrapper)
        {
            ViewModel.LinkWrapper = linkWrapper;
        }

        private void AddMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (!((e.OriginalSource as MenuItem).DataContext is Type))
                return;

            ILock lockItem = (ILock)Activator.CreateInstance((e.OriginalSource as MenuItem).DataContext as Type);
            ViewModel.AddLockWrapper(lockItem);
        }

        private void RemoveMenuItem_Click(object sender, RoutedEventArgs e)
        {
            PropertyCategory propertyCategory = (sender as FrameworkElement).DataContext as PropertyCategory;
            ViewModel.RemoveLockWrapper((LockWrapper)propertyCategory.AssociatedItem);
        }

        private void GameItemMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (e.OriginalSource == sender)
                return;

            MenuItem menuItem = e.OriginalSource as MenuItem;
            PropertyCategory propertyCategory = (sender as FrameworkElement).DataContext as PropertyCategory;
            GameItem gameItem = (menuItem.Header as GameItemWrapper).GameItem;
            string gameItemName = (gameItem != null) ? gameItem.Name : "";
            (propertyCategory.AssociatedItem as LockWrapper).SetGameItemName(gameItemName);
        }

        static private void CurrentLinkChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            LockEditorView view = (LockEditorView)dependencyObject;

            view.ViewModel.LinkWrapper = view.CurrentLink;
        }
    }

    public class LockEditorViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public LinkWrapper LinkWrapper { get { return linkWrapper; } set { SetLinkWrapper(value); } }
        public NotifiableCollection<Type> LockTypeCollection { get; private set; }
        public NotifiableCollection<PropertyCategory> Properties { get; private set; }

        private LinkWrapper linkWrapper;

        public LockEditorViewModel()
        {
            LockTypeCollection = new NotifiableCollection<Type>(GameEngine.ObtainAllTypes<ILock>("Pavilion.Locks.dll"));
            Properties = new NotifiableCollection<PropertyCategory>();
        }

        internal void AddLockWrapper(ILock lockItem)
        {
            linkWrapper.AddLockWrapper(new LockWrapper(lockItem, linkWrapper));

            LoadLocks();
        }

        internal void RemoveLockWrapper(LockWrapper lockWrapper)
        {
            LinkWrapper.RemoveLock(lockWrapper.Lock);

            LoadLocks();
        }

        private void LoadLocks()
        {
            ClearProperties();

            if (linkWrapper == null)
                return;

            foreach (LockWrapper lockWrapper in linkWrapper.LockWrapperCollection)
                Properties.Add(lockWrapper.PropertyCategory);
        }

        private void ClearProperties()
        {
            while (Properties.Count != 0)
                Properties.RemoveAt(0);
        }

        private void SetLinkWrapper(LinkWrapper value)
        {
            linkWrapper = value;
            OnPropertyChanged("LinkWrapper");

            if (linkWrapper != null)
                linkWrapper.Disposed += (x) => LinkWrapper = null;

            LoadLocks();
        }

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
